/**
 * 
 */
package badugi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * @author aleks
 *
 */
public class ServerThread extends Thread {
	private int nrOfPlayers;
	private int nrOfTokens;
	private int smallBlindValue;
	private int bigBlindValue;
	private Socket client;
	private int id;
	private ServerThread[] sequence;
	private BufferedReader in = null;
	private PrintWriter out = null;
	private String data = "";
	private String dataIn = "";
	private String statusInAction = "";
	private String whatIDo = "";
	private boolean isAllIn;
	private int inWhichRoundAllIn = 0;
	
	private int tokensInBet[] = new int[4];
	private boolean isInTheGame;
	private boolean playerWantToPlay = true;
	private String[] whatCanIDo;
	
	public void setWhatCanIDo (String avaliable) {
		int nrOfMoves = avaliable.length()/2;
		whatCanIDo = new String[nrOfMoves];
		int k = 0;
		for (int i = 0; i < nrOfMoves; i++) {
			whatCanIDo[i] = avaliable.substring(k, k+2);
			k +=2;
		}
	}
	
	private boolean canIDoIt (String action) {
		for (int i = 0; i < whatCanIDo.length; i++) {
			if (action.equals(whatCanIDo[i])) return true;
		}
		return false;
	}
	
	/**
	 * @return the whatIDo
	 */
	public String getWhatIDo() {
		return whatIDo;
	}
	/**
	 * @param whatIDo the whatIDo to set
	 */
	public void setWhatIDo(String whatIDo) {
		this.whatIDo = whatIDo;
	}
	public String getData() {
		return data;
	}
	/**
	 * @return the isAllIn
	 */
	public boolean isAllIn() {
		return isAllIn;
	}

	/**
	 * @param isAllIn the isAllIn to set
	 */
	public void setAllIn(boolean isAllIn, int round) {
		this.isAllIn = isAllIn;
		this.inWhichRoundAllIn = round;
	}
	
	public int getInWhichRoundAllIn() {
		return inWhichRoundAllIn;
	}

	public void setStatusInAction(String content) {
		statusInAction = content;
	}
	
	public String getStatusInAction() {
		return statusInAction;
	}
	
	public int getNrOfTokens() {
		return nrOfTokens;
	}
	
	/**
	 * @return the tokensInBet
	 */
	public int getTokensInBet(int whichRound) {
		return tokensInBet[whichRound];
	}

	/**
	 * @param tokensInBet the tokensInBet to set
	 */
	public void setTokensInBet(int tokensToBet, int whichRound) throws RoomException {
		this.nrOfTokens -= tokensToBet;
		if (nrOfTokens < 0) throw new RoomException(3);
		this.tokensInBet[whichRound] += tokensToBet;
	}
	
	public int allBettedMoney() {
		int sum = 0;
		for (int i = 0; i < tokensInBet.length; i++) {
			sum += tokensInBet[i];
		}
		return sum;
	}
	
	public void takePrize(int money) {
		nrOfTokens += money;
	}

	/**
	 * @return the isInTheGame
	 */
	public boolean isInTheGame() {
		return isInTheGame;
	}

	/**
	 * @param isInTheGame the isInTheGame to set
	 */
	public void setInTheGame(boolean isInTheGame) {
		this.isInTheGame = isInTheGame;
	}
	
	protected void sendToOut(String content) {
		out.println(content);
	}

	ServerThread(int nrOfPlayers, int nrOfTokens, int smallBlindValue, int bigBlindValue, Socket client, PrintWriter out, int counter, ServerThread[] sequence, Room room) {
		this.nrOfPlayers = nrOfPlayers;
		this.nrOfTokens = nrOfTokens;
		this.smallBlindValue = smallBlindValue;
		this.bigBlindValue = bigBlindValue;
		this.sequence = sequence;
		//this.room = room;
		this.client = client;
		this.id = counter;
		for (int i = 0; i < tokensInBet.length; i++) { tokensInBet[i] = 0; }
		setInTheGame(true);
		isAllIn = false;
		this.out = out;
		try {
			in = new BufferedReader(new InputStreamReader(client.getInputStream()));
			//out = new PrintWriter(client.getOutputStream(), true);
		}
		catch (IOException e) {
			System.out.println("Accept failed: 4444");
		}
	}
	
	public void prepareToTheNextMatch() {
		for (int i = 0; i < tokensInBet.length; i++) { tokensInBet[i] = 0; }
		setInTheGame(true);
		isAllIn = false;
		data = "";
		statusInAction = "";
		whatIDo = "";
	}
	
	public String checkStatus() {
		return statusInAction;
	}
	
	public void sayThatPlayerDontWantToPlay() {
		playerWantToPlay = false;
	}
	
	public void run() {
		try {
			System.out.println("We've a player with ID: " + id);
			synchronized(this) {
				for (int i = 0; i < sequence.length; i++) {
					if (sequence[i] != null && sequence[i] != this) {
						sequence[i].out.println("<" + id + "><02><" + id + "," + (int)(nrOfPlayers-(id+1)) + ">");
					}
				}
			}
			//out.println("<" + nrOfPlayers + "><01><" + id + "," + nrOfPlayers + "," + nrOfTokens + "," + smallBlindValue + "," + bigBlindValue + ">");
			String action = "";
			String betActionValue = "";
			String codeOfOperation = "";
			String tempString = "";
			int tempInt = 0;
			while (dataIn!=null && playerWantToPlay) {
				dataIn = in.readLine();
				if (dataIn != null) {
					System.out.println(id + "received: " + dataIn + "  " + statusInAction);
					codeOfOperation = dataIn.substring(4, 6);
					//if <06> licytacja
					if (codeOfOperation.equals("00")) {
						System.out.println("Player " + id + " disconnected");
						break;
					}
					else {
						if (statusInAction == "waiting") {
							if (codeOfOperation.equals("02")) {
								//System.out.println(id + "received in 02: " + dataIn);
								setStatusInAction("ready");
							}
							else if (codeOfOperation.equals("06")) {
								data = "";
								action = dataIn.substring(8,10);
								if (canIDoIt(action)) {
									betActionValue = dataIn.substring(11, dataIn.length()-1 );
									System.out.println("Player " + id + " wants: " + action + " with: " + betActionValue);
									setWhatIDo(action);
									try {
										tempInt = Integer.parseInt(betActionValue);
										data = betActionValue;
									}
									catch (NumberFormatException e){
										out.println("<" + nrOfPlayers + "><30><01>");
										setStatusInAction("waiting");
										break;
									}
									setStatusInAction("received");
								}
								else {
									System.out.println("Player " + id + " wants: " + action + ", but he can NOT do that! ");
									out.println("<" + nrOfPlayers + "><30><You cant do it>");
									setStatusInAction("waiting");
								}
							}
							else if (codeOfOperation.equals("08")) {
								action = dataIn.substring(8, 9);
                   System.out.println("Player " + id + " wants: " + action );
								data = "";
								try {
									if (action.equals("0")) {
										setWhatIDo(action);
										setStatusInAction("received");
									}
									else if (action.equals("1")) {
										setWhatIDo(action);
										tempString = dataIn.substring(10, 11);
										tempInt = Integer.parseInt(tempString);
										data += tempString;
										setStatusInAction("received");
									}
									else if (action.equals("2")) {
										setWhatIDo(action);
										tempString = dataIn.substring(10, 11);
										tempInt = Integer.parseInt(tempString);
										data += tempString;
										tempString = dataIn.substring(12, 13);
										tempInt = Integer.parseInt(tempString);
										data += tempString;
										setStatusInAction("received");
									}
									else if (action.equals("3")) {
										setWhatIDo(action);
										tempString = dataIn.substring(10, 11);
										tempInt = Integer.parseInt(tempString);
										data += tempString;
										tempString = dataIn.substring(12, 13);
										tempInt = Integer.parseInt(tempString);
										data += tempString;
										tempString = dataIn.substring(14, 15);
										tempInt = Integer.parseInt(tempString);
										data += tempString;
										setStatusInAction("received");
									}
									else if (action.equals("4")) {
										setWhatIDo(action);
										setStatusInAction("received");
									}
									else {
										out.println("<" + nrOfPlayers + "><30><01>");
										setStatusInAction("waiting");
									}
								}
								catch (NumberFormatException e){
									out.println("<" + nrOfPlayers + "><30><01>");
									setStatusInAction("waiting");
									break;
								}
							}
							else if (codeOfOperation.equals("10")) {
								data = dataIn.substring(8, 9);
								setStatusInAction("ready");
							}
							
						}
					}
				}
			}
			if (playerWantToPlay) {
				System.out.println("Player " + id + " disconnected; thread quits.");
			}
			else {
				System.out.println("Player " + id + " doesn't want to play with us; thread quits.");
			}
			
			in.close();
			out.close();
			client.close();
		}
		catch (IOException e) {
			System.out.println("Accept failed: 4444");
		}
	}

}
